using Microsoft.AspNetCore.Http;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Security.Principal;
using TianShu.DependencyInjection;
using TianShu.Security.Claims;

namespace TianShu.Users
{
    public class CurrentUser : ICurrentUser, ITransientDependency
    {
        private static readonly Claim[] EmptyClaimsArray = new Claim[0];

        public virtual bool IsAuthenticated => Id.HasValue;

        public virtual Guid? Id => _principalAccessor.Principal?.FindUserId();

        public virtual string Account => this.FindClaimValue(AbpClaimTypes.Account);

        public virtual string Name => this.FindClaimValue(AbpClaimTypes.Name);

        public virtual string UserName => this.FindClaimValue(AbpClaimTypes.UserName);

        public virtual string PhoneNumber => this.FindClaimValue(AbpClaimTypes.PhoneNumber);

        public virtual bool PhoneNumberVerified => string.Equals(this.FindClaimValue(AbpClaimTypes.PhoneNumberVerified), "true", StringComparison.InvariantCultureIgnoreCase);

        public virtual string Email => this.FindClaimValue(AbpClaimTypes.Email);

        public virtual bool EmailVerified => string.Equals(this.FindClaimValue(AbpClaimTypes.EmailVerified), "true", StringComparison.InvariantCultureIgnoreCase);

        public virtual Guid? TenantId => _principalAccessor.Principal?.FindTenantId();

        public virtual string[] Roles => FindClaims(AbpClaimTypes.Role).Select(c => c.Value).Distinct().ToArray();
        public virtual List<Guid> OrgIds => FindClaims(AbpClaimTypes.Org).Select(c => Guid.Parse(c.Value)).Distinct().ToList();

        public virtual string ShiftName => this.FindClaimValue(AbpClaimTypes.ShiftName);

        public virtual Guid? ShiftId => _principalAccessor.Principal?.FindShiftId();

        public virtual string ClassPeriodName => this.FindClaimValue(AbpClaimTypes.ClassPeriodName);

        public virtual Guid? ClassPeriodId => _principalAccessor.Principal?.FindClassPeriodId();

        private readonly ICurrentPrincipalAccessor _principalAccessor;

        public CurrentUser(ICurrentPrincipalAccessor principalAccessor)
        {
            _principalAccessor = principalAccessor;
        }

        public virtual Claim FindClaim(string claimType)
        {
            return _principalAccessor.Principal?.Claims.FirstOrDefault(c => c.Type == claimType);
        }

        public virtual Claim[] FindClaims(string claimType)
        {
            return _principalAccessor.Principal?.Claims.Where(c => c.Type == claimType).ToArray() ?? EmptyClaimsArray;
        }

        public virtual Claim[] GetAllClaims()
        {
            return _principalAccessor.Principal?.Claims.ToArray() ?? EmptyClaimsArray;
        }

        public virtual bool IsInRole(string roleName)
        {
            return FindClaims(AbpClaimTypes.Role).Any(c => c.Value == roleName);
        }
        //public IAbpLazyServiceProvider LazyServiceProvider { get; set; }
        //public virtual Guid? Id => _httpContextAccessor.HttpContext.GetGuidOrNullByKey("UserId");

        //public virtual string UserName => _httpContextAccessor.HttpContext.GetByKey(nameof(UserName));

        //public virtual string Name => _httpContextAccessor.HttpContext.GetByKey(nameof(Name));

        //public virtual string Account => _httpContextAccessor.HttpContext.GetByKey(nameof(Account));

        //public virtual string PhoneNumber => _httpContextAccessor.HttpContext.GetByKey(nameof(PhoneNumber));


        //public virtual string Email => _httpContextAccessor.HttpContext.GetByKey(nameof(Email));


        //public virtual Guid? TenantId => _httpContextAccessor.HttpContext.GetGuidOrNullByKey(nameof(TenantId));

        //public virtual string[] Roles => new string[] { };

        //public bool IsAuthenticated => Id != null;



        //private readonly IHttpContextAccessor _httpContextAccessor;

        //public CurrentUser(IHttpContextAccessor httpContextAccessor)
        //{
        //    _httpContextAccessor = httpContextAccessor;
        //}

        //public virtual string GetExtraPropertyValue(string key)
        //{
        //    return _httpContextAccessor.HttpContext.GetByKey(key);
        //}
    }
}
